package com.authine.cloudpivot.ext.utils;

import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.authine.cloudpivot.common.organization.feign.DepartmentFeignServiceI;
import com.authine.cloudpivot.common.organization.feign.UserFeignServiceI;
import com.authine.cloudpivot.metadata.design.dto.clientobject.domainmodel.schema.BizSchema;
import com.authine.cloudpivot.metadata.design.dto.clientobject.domainmodel.schema.Properties;
import com.authine.cloudpivot.metadata.design.dto.clientobject.domainmodel.schema.ValueType;
import com.authine.common.util.ObjectMapperUtils;
import com.authine.hermes.app.launcher.org.v2.DepartmentV2;
import com.authine.hermes.app.launcher.org.v2.UserV2;
import com.authine.hermes.app.launcher.service.OrgServiceV2;
import com.authine.hermes.model.flow.enums.type.UnitType;
import com.authine.mvp.app.launcher.common.SchemaHelper;
import com.authine.mvp.app.launcher.config.CacheService;
import com.authine.mvp.app.launcher.domain.AddrFormat;
import com.authine.mvp.app.launcher.domain.AttachmentFormat;
import com.authine.mvp.app.launcher.domain.SelectorFormat;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import com.authine.mvp.app.launcher.utils.BOUtils;
import com.authine.mvp.app.org.dto.domainvo.DeptOrUserVO;
import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.v3.core.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Slf4j
public class BoResultFormat{
    private static final CacheService cacheService = ApplicationContextUtils.getBean(CacheService.class);
    private static final DepartmentFeignServiceI departmentFeignServiceI = ApplicationContextUtils.getBean(DepartmentFeignServiceI.class);
    private static final UserFeignServiceI userServiceI = ApplicationContextUtils.getBean(UserFeignServiceI.class);
    private static final OrgServiceV2 orgServiceV2 = ApplicationContextUtils.getBean(OrgServiceV2.class);
    private static final int DEPARTMENT = 1;
    private static final int USER = 3;

    public static void resultFormat(List<Map<String, Object>> data, String schemaCode) {
        resultFormat(data, schemaCode, true);
    }

    public static void resultFormat(List<Map<String, Object>> data, String schemaCode, boolean isRadioToList) {
        BizSchema schema = cacheService.getBizSchema(schemaCode);
        log.info("临时调试日志打印  schema:{}",schema);
        Set<String> userIds = new HashSet<>();
        Set<String> departmentIds = new HashSet<>();
        Map<String, Properties> propertiesMap = schema.getProperties().stream().collect(Collectors.toMap(Properties::getCode, Function.identity()));
        for (Map<String, Object> map : data) {
            map.forEach((key, value) -> {
                if (BOUtils.isSystemUserCode(key)) {
                    if (value != null) {
                        userIds.add(value.toString());
                    }
                } else if (BOUtils.isSystemDeptCode(key)) {
                    if (value != null) {
                        departmentIds.add(value.toString());
                    }
                } else {
                    Properties properties = propertiesMap.get(key);
                    if (properties != null && value != null && !StringUtils.isEmpty(value.toString())) {
                        ValueType valueType = properties.getValueType();
                        if (ValueType.RADIO_PERSON == valueType || ValueType.RADIO_DEPARTMENT == valueType) {
                            SelectorFormat selectorFormat = ObjectMapperUtils.fromJSON(value.toString(), SelectorFormat.class);
                            if(isRadioToList == false){
                                map.put(key, selectorFormat);
                            }else{
                                map.put(key, Collections.singletonList(selectorFormat));
                            }
                        } else if (ValueType.ATTACHMENT == valueType || ValueType.IMAGE == valueType) {
                            List<AttachmentFormat> attachmentFormats = ObjectMapperUtils.readValue(value.toString(), AttachmentFormat.class);
                            map.put(key, attachmentFormats);
                        } else if (ValueType.MULTI_SELECT_DEPARTMENT == valueType || ValueType.MULTI_SELECT_PERSON == valueType || ValueType.PERSON_DEPARTMENT_SELECT == valueType) {
                            List<SelectorFormat> selectorFormats = ObjectMapperUtils.readValue(value.toString(), SelectorFormat.class);
                            map.put(key, selectorFormats);
                        } else if (ValueType.ADDR_TYPE == valueType || ValueType.MAP_TYPE == valueType) {
                            AddrFormat addrFormat = ObjectMapperUtils.fromJSON(value.toString(), AddrFormat.class);
                            map.put(key, addrFormat);
                        } else if (ValueType.MULTI_SELECT_TEXT == valueType) {
                            List<String> stringList = ObjectMapperUtils.readValue(value.toString(), String.class);
                            map.put(key, stringList);
                        } else if (ValueType.DATE == valueType) {
                            SimpleDateFormat sdf = new SimpleDateFormat(properties.getFormat());
                            map.put(key, sdf.format(value));
                        }
                    }
                }
            });
        }
        for (Map<String, Object> map : data) {
            map.forEach((key, value) -> {
                if (BOUtils.isSystemUserCode(key)) {
//                    map.put(key, value == null ? null : departmentFeignServiceI.getDetail(value.toString()).getData());
                    map.put(key, value == null ? null : orgServiceV2.getDepartment(value.toString()).getData());
                }else if(BOUtils.isSystemDeptCode(key)){
                    map.put(key, value == null ? null : orgServiceV2.getUserByUserId(value.toString()).getData());
                }
            });
        }
    }

    public static void initSys(String corpLoginId,   Map<String, Object> map) {
        map.putIfAbsent("id", SchemaHelper.getId());
        map.putIfAbsent("createdTime", new Date());
        map.putIfAbsent("createdBy", corpLoginId);
        String  departmentId = getDepartmentId(corpLoginId);
        map.putIfAbsent("createdDept", departmentId);
        map.putIfAbsent("owner", corpLoginId);
        map.putIfAbsent("ownerDept", departmentId);
        map.putIfAbsent("status", "finished");
    }

    public static String getDepartmentId(String corpLoginId) {
        SingleResponse<UserV2> response = orgServiceV2.getUserByUserId(corpLoginId);
        if (response.isSuccess()) {
            UserV2 userV2 = response.getData();
            if(userV2 != null){
                return userV2.getMainDepartmentId();
            }
            return null;
        } else {
            throw new BizException(response.getErrCode(), response.getErrMessage(), "");
        }
    }

    @NotNull
    public static SelectorFormat getMainDept(String corpLoginId) {
        String departmentId = getDepartmentId(corpLoginId);
        if(StringUtils.isEmpty(departmentId)){
            throw new BizException("-1", "登录用户部门信息异常", "");
        }
//        DepartmentVO detail = departmentFeignServiceI.getDetail(departmentId).getData();
        DepartmentV2 detail = orgServiceV2.getDepartment(departmentId).getData();
        SelectorFormat custmOrg = new SelectorFormat();
        custmOrg.setName(detail.getName());
        custmOrg.setId(detail.getId());
        custmOrg.setType(UnitType.DEPARTMENT.getIndex());
        return custmOrg;
    }

    private static void format(List<Map<String, Object>> data, BizSchema bizSchema) {
        Map<String, Properties> propertiesMap = bizSchema.getProperties().stream().collect(Collectors.toMap(Properties::getCode, Function.identity()));
        Iterator var4 = data.iterator();

        while(true) {
            if (!var4.hasNext()) {
                return;
            }
            Map<String, Object> map =(Map)var4.next();
            HashSet deleting = new HashSet();
            do {
                map.forEach((key, value) -> {
                    if (!key.equals(bizSchema.getModelId() + "_ext")) {
                        if (!key.equalsIgnoreCase("preNodeId") && !key.equalsIgnoreCase("nextNodeId")) {
                            Properties properties = propertiesMap.get(key);
                            if (properties != null && properties.getValueType() != ValueType.RELATION_KEY) {
                                if (value != null && org.apache.commons.lang3.StringUtils.isNotBlank(value.toString())) {
                                    ValueType valueType = properties.getValueType();
                                    if (ValueType.RADIO_PERSON != valueType && ValueType.RADIO_DEPARTMENT != valueType) {
                                        if (ValueType.MULTI_SELECT_DEPARTMENT != valueType && ValueType.MULTI_SELECT_PERSON != valueType && ValueType.PERSON_DEPARTMENT_SELECT != valueType) {
                                            if (ValueType.ADDR_TYPE == valueType || ValueType.MAP_TYPE == valueType || ValueType.ATTACHMENT == valueType || ValueType.IMAGE == valueType || ValueType.MULTI_SELECT_TEXT == valueType) {
                                                map.put(key, ObjectMapperUtils.toJSONString(value));
                                            }
                                        } else {
                                            map.put(key, ObjectMapperUtils.toJSONString(value));
                                        }
                                    } else if (!BOUtils.isSystemUserCode(key) && !BOUtils.isSystemDeptCode(key)) {
                                        map.put(key, ObjectMapperUtils.toJSONString(value));
                                    } else {
                                        if (value instanceof Map || value instanceof SelectorFormat || value instanceof DeptOrUserVO) {
                                            map.put(key, ((JsonNode) Json.mapper().convertValue(value, JsonNode.class)).get("id").asText());
                                        }

                                        if (value instanceof List) {
                                            Iterator var8 = ((List)value).iterator();

                                            while(var8.hasNext()) {
                                                Object o = var8.next();
                                                map.put(key, ((JsonNode)Json.mapper().convertValue(o, JsonNode.class)).get("id").asText());
                                            }
                                        }
                                    }
                                }
                            } else {
                                deleting.add(key);
                            }

                        }
                    }
                });
            } while(deleting.isEmpty());

            Iterator var7 = deleting.iterator();

            while(var7.hasNext()) {
                String s = (String)var7.next();
                map.remove(s);
            }
        }
    }
}